home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Devices / CD-ROM / How to Detect a CD / Not used in this example / Determine Devices using SCSI / cscsi.cp next >
Encoding:
Text File  |  1995-10-18  |  3.5 KB  |  190 lines  |  [TEXT/MPS ]

  1. #include        "CSCSI.h"
  2.  
  3. CSCSIOp::CSCSIOp( void )
  4. {
  5.     haveInfo = 0;
  6.     timeout = 60L;
  7. }
  8.  
  9. CSCSIOp::~CSCSIOp( void )
  10. {
  11. }
  12.  
  13. void    CSCSIOp::keep( short what )
  14. {
  15.     haveInfo = what;
  16. }
  17.  
  18. void    CSCSIOp::setID( short ID )
  19. {
  20.     targetID = ID;
  21.     haveInfo |= USE_ID;
  22. }
  23.  
  24. void    CSCSIOp::setCDB( short len, Byte * cdbPtr )
  25. {
  26.     short    i;
  27.     cdbLen = len;
  28.     for ( i = 0; i < len; i++ )
  29.             cdb[i] = *cdbPtr++;
  30.     haveInfo |= USE_CDB;
  31. }
  32.  
  33. void    CSCSIOp::set6( Byte a, Byte b, Byte c, Byte d, Byte e, Byte f )
  34. {
  35.     cdbLen = 6;
  36.     cdb[0] = a; cdb[1] = b; cdb[2] = c; cdb[3] = d; cdb[4] = e; cdb[5] = f;
  37.     haveInfo |= USE_CDB;
  38. }
  39.  
  40. void    CSCSIOp::set10( Byte a, Byte b, Byte c, Byte d, Byte e, Byte f,
  41.                                 Byte g, Byte h, Byte i, Byte j )
  42. {
  43.     cdbLen = 10;
  44.     cdb[0] = a; cdb[1] = b; cdb[2] = c; cdb[3] = d; cdb[4] = e; cdb[5] = f;
  45.     cdb[6] = g; cdb[7] = h; cdb[8] = i; cdb[9] = j;
  46.     haveInfo |= USE_CDB;
  47. }
  48.  
  49. void    CSCSIOp::set12( Byte a, Byte b, Byte c, Byte d, Byte e, Byte f,
  50.                                 Byte g, Byte h, Byte i, Byte j, Byte k, Byte l )
  51. {
  52.     cdbLen = 12;
  53.     cdb[0] = a; cdb[1] = b; cdb[2] = c; cdb[3] = d; cdb[4] = e; cdb[5] = f;
  54.     cdb[6] = g; cdb[7] = h; cdb[8] = i; cdb[9] = j; cdb[10] = k; cdb[11] = l;
  55.     haveInfo |= USE_CDB;
  56. }
  57.  
  58. void    CSCSIOp::setLen( long len )
  59. {
  60.     dataLen = len;
  61.     haveInfo |= USE_LEN;
  62. }
  63.  
  64. void    CSCSIOp::setBuf( void * buf )
  65. {
  66.     dataPtr = (Byte *)buf;
  67.     haveInfo |= USE_BUF;
  68. }
  69.  
  70. void    CSCSIOp::setDir( XferDir direction )
  71. {
  72.     dir = direction;
  73.     haveInfo |= USE_DIR;
  74. }
  75.  
  76. short    CSCSIOp::execute( void )
  77. {
  78.     SCSIInstr    xfer[3];
  79.     short        info = haveInfo;
  80.     
  81.     haveInfo = 0;
  82.     
  83.     if ( info & USE_DIR )
  84.     {
  85.         if ( dir == noData )
  86.         {
  87.             if ( (info & CAN_NO_DATA) != CAN_NO_DATA )
  88.             {
  89.                     return err = SCSI_NEED_INFO;
  90.             }
  91.         }
  92.         else if ( (info & CAN_DATA) != CAN_DATA )
  93.         {
  94.             return err = SCSI_NEED_INFO;
  95.         }
  96.     }
  97.     else
  98.             return err = SCSI_NEED_INFO;
  99.             
  100.     if ( dir != noData )
  101.     {
  102.         //
  103.         // SCSIManager seems to update scParam1 on scInc only if the scInc did
  104.         // not fail.  Thus, if we need to know the exact data count, we need
  105.         // to use a loop, doing on scInc for each byte.
  106.         //
  107.         // If the dataLen is not a multiple of 0x200, we assume the user needs
  108.         // to know the exact amount, and so we loop.  If the dataLen is a multiple
  109.         // of 0x200, we assume it is a read or write to a blocked device, and the
  110.         // user wants efficiency more than an exact byte count.
  111.         //
  112.         if ( dataLen & 0x1ff )
  113.         {
  114.             xfer[0].scOpcode = scInc;
  115.             xfer[0].scParam1 = (unsigned long)dataPtr;
  116.             xfer[0].scParam2 = 1;
  117.             xfer[1].scOpcode = scLoop;
  118.             xfer[1].scParam1 = -10;
  119.             xfer[1].scParam2 = dataLen;
  120.             xfer[2].scOpcode = scStop;
  121.         }
  122.         else
  123.         {
  124.             xfer[0].scOpcode = scInc;
  125.             xfer[0].scParam1 = (unsigned long)dataPtr;
  126.             xfer[0].scParam2 = dataLen;
  127.             xfer[1].scOpcode = scStop;
  128.         }
  129.     }
  130.     
  131.     moved = 0;
  132.     
  133.     err = SCSIGet();
  134.     if ( err )
  135.         return err;
  136.             
  137.     err = SCSISelect( targetID );
  138.     if ( err )
  139.         return err;
  140.             
  141.     err = SCSICmd( (Ptr)cdb, cdbLen );
  142.     if ( err )
  143.     {
  144.         SCSIComplete( &status, &message, 60L );
  145.         return err;
  146.     }
  147.     
  148.     if ( dir == dataIn )
  149.         err = SCSIRead( (Ptr)xfer );
  150.     else if ( dir == dataOut )
  151.         err = SCSIWrite( (Ptr)xfer );
  152.             
  153.     moved = xfer[0].scParam1 - (unsigned long)dataPtr;
  154.     
  155.     if ( err && err != scPhaseErr )
  156.     {
  157.         SCSIComplete( &status, &message, 60L );
  158.         return err;
  159.     }
  160.     
  161.     err = SCSIComplete( &status, &message, timeout );
  162.     
  163.     return err;
  164. }
  165.  
  166. short    CSCSIOp::getStatus( void )
  167. {
  168.     return status;
  169. }
  170.  
  171. short    CSCSIOp::getMessage( void )
  172. {
  173.     return message;
  174. }
  175.  
  176. void    CSCSIOp::setTimeout( long newTime )
  177. {
  178.     timeout = newTime;
  179. }
  180.  
  181. OSErr    CSCSIOp::getErr( void )
  182. {
  183.     return err;
  184. }
  185.  
  186. long    CSCSIOp::getMoved( void )
  187. {
  188.     return moved;
  189. }
  190.